package com.moody.web.intercept;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

import com.moody.hibernate.dao.CodeLibDAO;
import com.moody.hibernate.dao.CustInfoDAO;
import com.moody.hibernate.dao.IndInfoDAO;
import com.moody.hibernate.dao.PdHDAO;
import com.moody.hibernate.domain.CustInfo;
import com.moody.hibernate.domain.IndInfo;
import com.moody.hibernate.domain.PdH;
import com.moody.hibernate.domain.ReportList;
import com.moody.hibernate.domain.RoleInfo;
import com.moody.hibernate.domain.UserInfo;
import com.moody.service.CustomerService;
import com.moody.service.SystemService;

/*
 * Copyright © Moody analytics   
 *
 * @Title: InterceptServlet.java 
 * @Package： com.moody.web 
 * @author： Fuqiang Wang
 * @Description: TODO(用一句话描述该文件做什么)    
 * @date： 2012-6-3 下午3:42:53
 * @Modified by: Fuqiang Wang 
 * @version V1.0   
 */

public class InterceptServlet extends HttpServlet implements Filter {
	private static final Logger log = LoggerFactory
			.getLogger(InterceptServlet.class);
	

	public InterceptServlet() {
		super();
	}

	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0;
		HttpServletResponse response = (HttpServletResponse) arg1;
		response.setHeader("ContentType", "text/json");  
        response.setCharacterEncoding("utf-8");  
		HttpSession session = request.getSession(true);
		String url = request.getRequestURI();
		log.info("url: " + url);
		
		WebApplicationContext web = ContextLoader.getCurrentWebApplicationContext();
		ServletContext context = web.getServletContext();  
		WebApplicationContext ctx  = WebApplicationContextUtils.getWebApplicationContext(context);
		CustInfoDAO custInfoDAO = CustInfoDAO.getFromApplicationContext(ctx);
		IndInfoDAO indInfoDAO = IndInfoDAO.getFromApplicationContext(ctx);
		PdHDAO pdhDAO = PdHDAO.getFromApplicationContext(ctx);
		
		
		
		
	
		// 如果是未登陆
		if (url.equals("/CRRS/") || url.indexOf("login") > 0
				|| url.indexOf("logout") > 0 || url.equals("/CRRS/view/Cover.jsp")) {
			arg2.doFilter(arg0, arg1);
		} else {

			// 已登录
			UserInfo user = ((UserInfo) session.getAttribute("logonUser"));
			if (user == null) {
				request.getRequestDispatcher("/view/timeout.jsp").forward(
						request, response);

				return;
			} else {
				String userId = user.getUserId();
				log.info("userId: " + userId);
				
				RoleInfo roleInfo = null;
				if(request.getSession().getAttribute("logonUserRole")!=null){
					roleInfo = (RoleInfo) request.getSession().getAttribute("logonUserRole");
				}
				
				//测试资本测算与风险定价功能时，专门针对测试部门给出权限：
				//当访问该页面并且非测试部门人员时：
				if((url.contains("DebtEC_CustomerList.jsp") || url.contains("PriceRaroc_CustomerList.jsp"))&& !user.getBelongorg().equals("fb808888391a8a1201391d5d81830004")){
					log.info("无权限访问");
					response.getWriter().print("{success:false}");
					request.getRequestDispatcher("/view/Forbid.jsp").forward(
							request, response);
					return;
				}
				//end：测试
				
				
				
				//只有管理员能进行删除 TODO 待确认
				if(url.contains("delete")){
					if(roleInfo.getRoleName().contains("系统管理员") || roleInfo.getRoleName().contains("超级管理员")){
						log.info("有权限增删改");
						arg2.doFilter(arg0, arg1);
					}else{
						log.info("无权限访问");
						response.getWriter().print("{success:false}");
						request.getRequestDispatcher("/view/Forbid.jsp").forward(
								request, response);
						return;
					}
				}

				// 如果链接是增删改，则先验证增删改的权限
				if (url.contains("edit")|| url.contains("modify") || url.contains("add") || url.contains("save")) {
					CustInfo custInfo = (CustInfo) session
							.getAttribute("custInfo");
					

					String custId = request.getParameter("CustId");
					//如果session中没有，从request中读取
					if(custInfo ==null){
						if(custId == null || custId.equals("")){
						}else{
							custInfo = custInfoDAO.findById(custId);
						}
					}
					
					//考虑零售客户的情况
					IndInfo indInfo = null;
					Object indCustId  = request.getSession().getAttribute("indCustId");
					if(indCustId != null){
						if(indCustId != null && !indCustId.toString().equals("")){
							indInfo = indInfoDAO.findById(indCustId.toString());
						}else{
							indCustId = request.getParameter("CustId");
							indInfo = indInfoDAO.findById(indCustId.toString());
						}
					}
					
					
					//如果是管理员修改系统管理中的信息，管理员能登录，则亦有权限修改
					String type = request.getParameter("type");
					//这个type用来标记是提交请求还是页面上的链接请求，例如saveBalance
					//对于链接请求，type为空，则开放权限，对于提交请求，type为0或者1，则除本人外无权限
					if ((custInfo != null &&  userId.equals(custInfo.getInputUserId())) 
							|| (indInfo !=null && userId.equals(indInfo.getInputUserId()))
							|| url.contains("/system/") || url.contains("/model/")
							|| (url.contains("addMain") &&  roleInfo.getRoleName()!=null && roleInfo.getRoleName().contains("客户经理")) 
							|| (url.contains("addRetailMain") && roleInfo.getRoleName()!=null && roleInfo.getRoleName().contains("客户经理"))
							|| ((url.contains("addCollateral")||url.contains("editCollateral")) && roleInfo.getRoleName()!=null && roleInfo.getRoleName().contains("客户经理"))
							|| (url.contains("addGuarantor") && roleInfo.getRoleName()!=null && roleInfo.getRoleName().contains("客户经理"))
							|| (type==null && url.contains("save"))) {
						
						/*
						 * 复评，审核，和认定状态，财报不允许修改
						 * 做法是查看session中是哪个客户的哪期财报，之后去pd中找此客户的这期财报，看是否有不允许修改的状态，
						 * 如果有，则不能修改，反之能修改
						 */
						
						//开放权限标志
						boolean flag = true;
						//判断是保存报表
						if(custInfo != null &&  userId.equals(custInfo.getInputUserId()) && type!=null && url.contains("save")){
							ReportList report = new ReportList();
							report = (ReportList) request.getSession().getAttribute("report");
							
							if(report!=null){
								List<PdH> list = pdhDAO.findAllPDByCustId(custInfo.getCustId());
								for(PdH pdh : list){
									String accountMonth = report.getId().getAccountMonth();
									if(accountMonth!=null && accountMonth.equals(pdh.getReportDate())){
										String status = pdh.getPhaseStat();
										if(status!=null && status.equals("02") || status.equals("03")|| 
												status.equals("04")|| status.equals("06")){
											flag = false;
										}
									}
								}
							}
						}
						
						if(flag){
							log.info("有权限增删改");
							arg2.doFilter(arg0, arg1);
						}else{
							log.info("无权限访问");
							response.getWriter().print("{success:false}");
							request.getRequestDispatcher("/view/Forbid.jsp").forward(
									request, response);
							return;
						}
						
						return;
					} else {
						log.info("无权限访问");
						
						response.getWriter().print("{success:false}");
						if(!url.contains("delete"))
						request.getRequestDispatcher("/view/Forbid.jsp").forward(
								request, response);
						
						return;
					}
				}

				// 如果不是增删改，验证其他权限
				String accessURL = "";
				String deniedURL = "";
				//过滤掉不需要拦截的连接，比如如果是下拉列表这种，则直接可以访问
				if(url.contains("/CRRS/show") || url.contains("/CRRS/dispatch") ){
					log.info("有权限访问");
					arg2.doFilter(arg0, arg1);
					return;
				}
				
				
				//如果是需要通过RightInfo中的URL控制
				if (request.getSession().getAttribute("accessURL") != null) {
					accessURL = request.getSession().getAttribute("accessURL")
							.toString();
					//去除换行
					accessURL = accessURL.replaceAll("\r\n", "");
					accessURL = accessURL.replaceAll("\n", "");
					deniedURL = request.getSession().getAttribute("deniedURL").toString();
					deniedURL = deniedURL.replaceAll("\r\n", "");
					deniedURL = deniedURL.replace("\n", "");
					String[] accessArray = accessURL.split(";");
					Boolean flag = false;
					
					//如果允许访问中有权限，则deniedURL中移除掉此类权限
					for(String s : accessArray){
						if(deniedURL.contains(s) && !s.equals("/obligation/")){
							deniedURL = deniedURL.replaceAll(s, "");
						}
					}
					
					//如果是禁止列表中的url，则直接拦截
					String[] deniedArray = deniedURL.split(";");
					for(String s : deniedArray){
						if(!s.equals("") && url.contains(s)){
							log.info("无权限访问");
							response.getWriter().print("{success:false}");
							request.getRequestDispatcher("/view/Forbid.jsp").forward(
									request, response);
							
							return;
						}
					}
					
					//否则去判断此url是否在权限列表中
					for (String s : accessArray) {
						if ( !s.equals("") && url.contains(s) ) {
							flag = true;
							break;
						}
					}

					if (flag) {
						log.info("有权限访问");
						arg2.doFilter(arg0, arg1);
						return;
					} else {
						log.info("无权限访问");
						response.getWriter().print("{success:false}");
						request.getRequestDispatcher("/view/Forbid.jsp").forward(
								request, response);
						
						return;
					}

				} else {
					log.info("无权限访问");
					response.getWriter().print("{success:false}");
					request.getRequestDispatcher("/view/Forbid.jsp").forward(
							request, response);
					
					return;
				}
			}
		}
	}

	public void init(FilterConfig arg0) throws ServletException {

	}

}
